import path from 'path'
import fs from 'node:fs'
// 解析 env文件
import { parse } from 'dotenv'

import { expand } from 'dotenv-expand'

const envList = [
  '.env',
  '.env.development',
  '.env.development.local'
]


function tryStatSync (file) {
  try {
    return fs.statSync(file, { throwIfNoEntry: false })
  } catch (error) {
    // 忽略错误
  }
}

// vite 源码中是 连贯嵌套写法，这里只是将每一个步骤拆分，可以打印输出查看内容
// packages/vite/src/node/env.ts  中 loadEnv 方法

let r1 = envList.flatMap(file => {
  /**
   * 拿到完整的文件路径
   * D:\owner\node-base-example\cac-demo\vite\.env
    D:\owner\node-base-example\cac-demo\vite\.env.development
    D:\owner\node-base-example\cac-demo\vite\.env.development.local
   */
  const filePath = path.join(process.cwd(), 'vite', file)

  // 尝试解析文件，读取文件是否存在
  // console.log(tryStatSync(filePath));

  /**
   * Stats {
    dev: 2793138336,
    mode: 33206,
    nlink: 1,
    uid: 0,
    gid: 0,
    rdev: 0,
    blksize: 4096,
    ino: 562949958349813,
    size: 0,
    blocks: 0,
    atimeMs: 1704270080630.521,
    mtimeMs: 1704270080630.521,
    ctimeMs: 1704270080630.521,
    birthtimeMs: 1704270080630.521,
    atime: 2024-01-03T08:21:20.631Z,
    mtime: 2024-01-03T08:21:20.631Z,
    ctime: 2024-01-03T08:21:20.631Z,
    birthtime: 2024-01-03T08:21:20.631Z
}
   */

  // 如果不是文件，就跳过
  if (!tryStatSync(filePath)?.isFile()) return []

  // 符合配置的.env文件，也就是项目根目录配置了这个文件的，就进入这个流程

  let content = fs.readFileSync(filePath)

  // console.log(content);
  // return Object.entries(parse())

  // 读取到的 content 是二进制内容 buffer
  // 使用 dotenv包进行解析
  let t1 = parse(content)
  // console.log('t1');
  // console.log(t1);

  // { VITE_PORT: '3000' }
  // { VITE_DIR: 'src' }
  // console.log(t1);

  return Object.entries(t1)
})

// [ [ 'VITE_PORT', '3000' ], [ 'VITE_DIR', 'src' ] ]
console.log('r1');
console.log(r1);

// 将数组对象变成 纯对象
const parsed = Object.fromEntries(r1)

/**
 {
  VITE_PORT: '3000',
  VITE_BASE_URL: 'http://www.baidu.com',
  VITE_OA_URL: '${VITE_BASE_URL}/api/oa',
  VITE_DIR: 'src'
}
 */
// console.log(parsed);
// 现在上述的 parsed 只是一个对象，并不具备 在 env中支持变量的行为

let t2 = expand({ parsed: parsed })

// console.log(t2);

/**
 * t2 = {
  parsed: {
    VITE_PORT: '3000',
    VITE_BASE_URL: 'http://www.baidu.com',
    VITE_OA_URL: 'http://www.baidu.com/api/oa',
    VITE_DIR: 'src'
  }
}
 */

// expand 修改的是 parsed 变量的引用， 所以，可以不定义 t2接收值


/**
解析以后，就是将变量进行了替换
{
  VITE_PORT: '3000',
  VITE_BASE_URL: 'http://www.baidu.com',
  VITE_OA_URL: 'http://www.baidu.com/api/oa',
  VITE_DIR: 'src'
}
 */
console.log(parsed);

// 检查env环境变量里面的前缀， 如果前缀以 VITE_ 开头的， 则保存到 env = {}  对象中

const env = {}

// 这里写死， vite源码中是默认值是 VITE_， 用户可以在 vite.config.js 中 修改配置 envPrefix 传递多个前缀
const prefixes = ['VITE_']

for (const [key, value] of Object.entries(parsed)) {
  // 如果 解析后的前缀，符合 前缀要求，则存储到 env 对象上
  if (prefixes.some((prefix) => key.startsWith(prefix))) {
    env[key] = value
  }
}

console.log('最终解析的结果');
console.log(env);